package com.example.OnlineStorage.Controller.User;


import com.example.OnlineStorage.enums.GlobalVariables_String;
import com.example.OnlineStorage.pojo.Response.ApiResponse;
import com.example.OnlineStorage.pojo.Response.ResponseData;
import com.example.OnlineStorage.pojo.entity.User;
import com.example.OnlineStorage.util.Redis;
import com.example.OnlineStorage.service.User.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户API控制器
 * 这个控制器负责处理用户相关的API请求。
 */
@Tag(name = "用户API")
@RestController("User")
@RequestMapping("/User")
public class UserController {
    private final UserService UserService;

    // 用户令牌的全局变量
    private final String TOKEN = GlobalVariables_String.TOKEN.getValue();

    public UserController(UserService UserService) {
        this.UserService = UserService;
    }

    /**
     * 用户注册。
     *
     * @param user 待注册的用户信息。
     * @return 注册结果的API响应。
     */
    @Operation(summary = "注册")
    @PostMapping("/register")
    public ResponseEntity<Object> register(@Validated @RequestBody User user) {
        return ApiResponse.GetApiResponse()
                .ok()
                .body(UserService.register(user))
                .build();
    }

    /**
     * 通过用户名登录。
     *
     * @param user 包含用户名和密码的用户信息。
     * @return 登录结果的API响应，包括用户信息和令牌。
     */
    @Operation(summary = "登录_用户名", description = "根据用户名登录")
    @PostMapping(value = "/login_username")
    public ResponseEntity<Object> login_username(@RequestBody User user) {
        user = UserService.login_username(user);
        Map<String, Object> map = new HashMap<>();
        map.put("data", user);
        String token = Redis.HGET(user.getUsername(), "UUID");
        return ApiResponse.GetApiResponse()
                .ok()
                .addHeader(TOKEN, token)
                .body(map)
                .build();
    }

    /**
     * 通过邮箱登录。
     *
     * @param user 包含邮箱和密码的用户信息。
     * @return 登录结果的API响应，包括用户信息和令牌。
     */
    @Operation(summary = "登录_邮箱", description = "根据邮箱登录")
    @PostMapping("/login_email")
    public ResponseEntity<Object> login_email(@RequestBody User user) {
        user = UserService.login_email(user);
        Map<String, Object> map = new HashMap<>();
        map.put("data", user);
        String token = Redis.HGET(user.getUsername(), "UUID");
        return ApiResponse.GetApiResponse()
                .ok()
                .addHeader(TOKEN, token)
                .body(map)
                .build();
    }

    /**
     * 更新用户信息。
     *
     * @param user    新的用户信息。
     * @return 更新结果的API响应。
     */
    @Operation(summary = "修改信息", description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @PostMapping("/updateUser")
    public ResponseEntity<Object> updateUser(@RequestBody User user, HttpServletRequest request) {
        user = UserService.updateUser(user, request.getHeader(TOKEN));
        Map<String, Object> map = new HashMap<>();
        map.put("data", user);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(map)
                .build();
    }

    /**
     * 上传用户头像。
     *
     * @param Avatar     用户上传的头像文件。
     * @param fileSHA256 头像文件的SHA256校验码。
     * @return 更新后的用户信息的API响应。
     */
    @Operation(summary = "上传头像", description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "Avatar", description = "用户上传的头像文件", required = true),
            @Parameter(name = "fileSHA256", description = "头像文件的SHA256校验码", required = true),
    })
    @PostMapping("/putAvatar")
    public ResponseEntity<Object> putAvatar(@RequestParam MultipartFile Avatar,
                                            @RequestParam String fileSHA256,
                                            HttpServletRequest request) {
        User user = UserService.putAvatar(Avatar, fileSHA256, request.getHeader(TOKEN));
        Map<String, Object> map = new HashMap<>();
        map.put("data", user);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(map)
                .build();
    }

    /**
     * 获取用户头像。
     *
     * @param Avatar 头像的标识。
     * @return 头像文件的API响应。
     */
    @Operation(summary = "获取头像")
    @Parameters({
            @Parameter(name = "Avatar", description = "头像的地址", required = true),
    })
    @GetMapping("/Not_verified/getAvatar")
    public ResponseEntity<ResourceRegion> getAvatar(@RequestParam String Avatar, HttpServletRequest request) {
        String Range = request.getHeader(HttpHeaders.RANGE);
        ResponseData responseData = UserService.getAvatar(Avatar, Range);
        return ApiResponse.GetApiResponse()
                .binBody(responseData)
                .onlineBuild();
    }

    /**
     * 修改用户密码。
     *
     * @param oldPassword  用户当前密码。
     * @param newPassword  用户新密码。
     * @param newPassword2 新密码的确认。\
     * @return 修改密码结果的API响应。
     */
    @Operation(summary = "修改密码", description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "oldPassword", description = "用户当前密码", required = true),
            @Parameter(name = "newPassword", description = "用户新密码", required = true),
            @Parameter(name = "newPassword2", description = "新密码的确认", required = true),
    })
    @PostMapping("/updatePassword")
    public ResponseEntity<Object> updatePassword(@RequestParam String oldPassword,
                                                 @RequestParam String newPassword,
                                                 @RequestParam String newPassword2,
                                                 HttpServletRequest request) {
        UserService.updatePassword(oldPassword, newPassword, newPassword2, request.getHeader(TOKEN));
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "密码修改成功");
        return ApiResponse.GetApiResponse()
                .ok()
                .body(map)
                .build();
    }

    /**
     * 用户注销。
     *
     * @param request 包含用户令牌的HTTP请求。
     * @return 注销结果的API响应。
     */
    @Operation(summary = "注销", description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @DeleteMapping("/logout")
    public ResponseEntity<Object> logout(HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        UserService.logout(UUID);
        return ApiResponse.GetApiResponse()
                .ok()
                .body("已注销")
                .build();
    }

    /**
     * 查询用户名是否重复。
     *
     * @param username 待查询的用户名。
     * @return 查询结果的API响应。
     */
    @Operation(summary = "查询用户名是否重复")
    @Parameters({
            @Parameter(name = "username", description = "待查询的用户名", required = true)
    })
    @PostMapping("/Not_verified/repeatUsername")
    public ResponseEntity<Object> repeatUsername(@RequestParam String username) {
        return ApiResponse.GetApiResponse()
                .ok()
                .body(UserService.repeatUsername(username))
                .build();
    }

    /**
     * 查询邮箱是否重复。
     *
     * @param email 待查询的邮箱。
     * @return 查询结果的API响应。
     */
    @Operation(summary = "查询邮箱是否重复")
    @Parameters({
            @Parameter(name = "email", description = "待查询的邮箱", required = true)
    })
    @PostMapping("/Not_verified/repeatEmail")
    public ResponseEntity<Object> repeatEmail(@RequestParam String email) {
        return ApiResponse.GetApiResponse()
                .ok()
                .body(UserService.repeatEmail(email))
                .build();
    }
}
